package com.example.mall.user.svc.domain.service;

import com.example.mall.common.constants.BaseEnum;
import com.example.mall.common.constants.CodeEnum;
import com.example.mall.common.exception.BizException;
import com.example.mall.user.svc.app.cmd.BindCmd;
import com.example.mall.user.svc.domain.model.entity.User;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Optional;

/**
 * @author Mickey
 * @since 2022/4/17
 **/
public interface Bind {

    void bind(User user, BindCmd<?> bind);

    void unbind(User user, BindCmd<?> bind);

    void change(User user, BindCmd<?> bind);

    @Getter
    @AllArgsConstructor
    enum BindCmdHandler implements BaseEnum<BindCmdHandler> {

        BIND(0, "绑定", (user, bindCmd, bind) -> bind.bind(user, bindCmd)),
        UNBIND(1, "解绑", (user, bindCmd, bind) -> bind.unbind(user, bindCmd)),
        CHANGE(2, "改邦", (user, bindCmd, bind) -> bind.change(user, bindCmd)),
        ;

        private final Integer code;
        private final String name;
        private final BindHandler bindHandler;

        public static BindCmdHandler of(Integer code) {
            return Optional.ofNullable(BaseEnum.parseByCode(BindCmdHandler.class, code)).orElseThrow(() -> new BizException(CodeEnum.FAIL));
        }

    }

    @FunctionalInterface
    interface BindHandler {
        void accept(User user, BindCmd<?> bindCmd, Bind bind);
    }

}
